import fs from "fs";
import path from "path";
import pLimit from "p-limit";
import cliProgress from "cli-progress";
import { sleep, getFollowingPageData2, getImageUrl } from "../../utils/canvasUtils.js";
import { axiosInstance as axios, fileUtils } from "./axios.js";
import { CardItem } from "./type.js";
interface img {
    url: string;
    token: string;
}
interface ImageInfo {
    url: string,
    token: string;
}



main()

async function main() {
    try {
        const config = fileUtils.config;
        const lastTokenMap: any = config.lastTokenMap;
        const lastPageMap: any = config.lastPageMap;

        for (const startToken in lastTokenMap) {
            console.log(`正在接续获取${startToken}的所有Token,目前是第${lastPageMap[startToken].page + 1}页`);

            let lastToken = (await scratchToken(lastTokenMap[startToken], startToken)).token;
            if (!lastToken) {
                console.log(`获取${startToken}的图片结束`);
                continue;
            }
            console.log(`获取到${startToken}的Token: ${lastToken}`);
            console.log(`获取${startToken}的图片结束`);
        }
    } catch (e) {
        fileUtils.logError(e);
        process.exit(1);
    }
}

//====================通过【1】通过请求获取Token=================
//通过给定的token，循环下拉式获取后续的Token，直到没有更多Token为止
async function scratchToken(token: string, path: string): Promise<{ data: CardItem[], token: string }> {
    const currentConfig: any = fileUtils.config;
    const lastPageMap: any = currentConfig.lastPageMap;
    const lastPage = lastPageMap[path].page;
    const end = lastPageMap[path].end;
    let data = [] as CardItem[];

    for (let i = 1 + lastPage; i < 98; i++) {
        if (i >= 97) { break }
        console.log(i);
        const res = await getFollowingPageData2(token, 100);
        const total = (res.total) / 100;
        if (i > total) { break }
        if (end && i > end) { break; }
        const dataList: ImageInfo[] = res.urlList;
        const urlList = dataList.map(item => {
            return {
                url: item.url,
                token: item.token
            }
        })
        console.log("获取到一批图片url，准备下载图片.");
        sleep(1000, 3000);
        await downloadImgs(path, urlList);
        token = res.continuationToken;
        lastTokenHandle(path, token, i);
    }
    return { data, token };
}

// ===================== 【2】下载图片到本地 =====================
//纯函数： 下载图片，并重试三次
async function downloadImgWithRetry(
    imgUrl: string,
    filePath: string,
    retries = 3
) {
    // 如果文件已经存在，则直接返回
    if (fs.existsSync(filePath)) {
        return;
    }
    try {
        const res = await axios.get(imgUrl, {
            responseType: "arraybuffer",
        });
        fs.writeFileSync(filePath, Buffer.from(res.data));
    } catch (error) {
        if (retries > 0) {
            console.log(`⚠️ 图片下载失败，重试中...`);
            sleep(1000, 1000);
            return downloadImgWithRetry(imgUrl, filePath, retries - 1);
        } else {
            fileUtils.logError(error);
        }
    }
}
//图片下载函数的封装
async function downloadImgs(keyword: string, imgUrls: img[]) {
    const res = await getType()
    console.log(`🔥 开始下载 ${imgUrls.length} 张图片`);
    const rowdir = path.resolve(fileUtils.outDirPath, res);
    const dir = path.resolve(rowdir, keyword);
    fs.mkdirSync(dir, { recursive: true }); //确保目录存在
    const limit = pLimit(fileUtils.config.concurrency); // 限制下载并发

    // 初始化进度条
    const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.rect);
    progressBar.start(imgUrls.length, 0);
    const promises = imgUrls.map(async (imgUrl) => {
        //文件名处理
        const filePath = await fileNameHandle(imgUrl.token, dir);
        return limit(async () => {
            await downloadImgWithRetry(imgUrl.url, filePath);
            progressBar.increment(); // 更新进度条
        });
    });

    await Promise.all(promises);
    progressBar.stop(); // 停止进度条
}

//====================【3】参数处理===========================
//文件名处理函数
const fileNameHandle = async (imgUrl: string, dir: string): Promise<string> => {
    const fileName = `${imgUrl}.jpg`;
    const filePath = `${dir}/${fileName}`;
    return filePath;
};
//下载参数处理函数
const lastTokenHandle = (path: string, token: string, index: number) => {
    const currentConfig: any = fileUtils.config;
    const userToken = token || '';
    if (!currentConfig.lastTokenMap) {
        currentConfig.lastTokenMap = {};
    }
    if (!currentConfig.lastPageMap) {
        currentConfig.lastPageMap = {};
    }
    currentConfig.lastPageMap[path].page = index;
    currentConfig.lastTokenMap[path] = userToken;
    fileUtils.writeConfig(currentConfig);
}
//获取下载类型
const getType = async () => {
    const config = fileUtils.config;
    const type = config.type;
    const res = `${type}/`
    return res;
}




